package com.itdfq.consumer.consumer;


import org.springframework.amqp.rabbit.config.RetryInterceptorBuilder;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryListener;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.backoff.NoBackOffPolicy;
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;

/**
 * @Author: QianMo
 * @Date: 2021/11/16 10:38
 * @Description:
 */
@Configuration
public class ReceiverDemo2Config {

    @Autowired
    private ConnectionFactory connectionFactory;

    @Autowired
    private ReceiverDemo2 receiverDemo2;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RejectDemoRecover rejectDemoRecover;


    @Bean
    public SimpleMessageListenerContainer config() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        // 配置队列信息
        container.setQueueNames("queue_name");
        container.setConnectionFactory(connectionFactory);
        // 配置重试
        container.setAdviceChain(RetryInterceptorBuilder.stateless()
                .recoverer(new RepublishMessageRecoverer(rabbitTemplate,"exchange_name",
                                "routing_key")
                        ).retryOperations(retryTemplate()).build());
        container.setMessageListener(receiverDemo2);
        return container;
    }


    private RetryOperationsInterceptor createRetry() {
        RetryTemplate retryTemplate = new RetryTemplate();
        retryTemplate.registerListener(new RetryListener() {
            @Override
            public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
                // 第一次重试调用
                System.out.println("第一次重试");
                return false;
            }

            @Override
            public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
                // 最后一次重试会调用
                System.out.println("最后一次重试");
            }

            @Override
            public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
                // 每次重试失败后都会调用
                System.out.println("每次重试都调用");
            }
        });
        //设置重试策略 SimpleRetryPolicy简单重试策略 设置重试次数
        retryTemplate.setRetryPolicy(new SimpleRetryPolicy(5));
        //设置重试回退策略
        retryTemplate.setBackOffPolicy(new NoBackOffPolicy());
        return RetryInterceptorBuilder.stateless()
                .retryOperations(retryTemplate).recoverer(rejectDemoRecover).build();
    }

    @Bean
    public RetryTemplate retryTemplate() {
        RetryTemplate retryTemplate = new RetryTemplate();
        //重试三次
        SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy(5);
        retryTemplate.setRetryPolicy(simpleRetryPolicy);
        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
        //重试间隔  5秒
        backOffPolicy.setInitialInterval(5000);
        retryTemplate.setBackOffPolicy(backOffPolicy);
        return retryTemplate;
    }


}
